﻿using System;
using System.Collections;
using System.Text;
using System.IO;
using System.ComponentModel;
using System.Windows.Forms;
using System.Diagnostics;
using Microsoft.VisualBasic;
using System.Collections.Generic;

namespace Easycmd
{
    public class FileUtils
    {
        static public string CheckSlash(string dir)
        {
            if (!(dir.Substring(dir.Length - 1, 1) == "\\"))
                dir += "\\";
            return dir;
        }
        static public void CopyFilesAndDirsToDir(ArrayList files, ArrayList dirs, string DstDir, bool move)
        {
            ArrayList r = new ArrayList();
            FileInfo fi = null;
            DirectoryInfo di = null;
            // copy files 
            foreach (string fullname in files)
            {
                fi = new FileInfo(fullname);
                di = new DirectoryInfo(DstDir);
                if (!di.Exists)
                {
                    di.Create();
                }
                try
                {
                    if (!move)
                        fi.CopyTo(CheckSlash(DstDir) + fi.Name);
                    else
                        fi.MoveTo(CheckSlash(DstDir) + fi.Name);
                }
                catch (Exception e)
                {
                    MessageBox.Show(e.Message);
                }
            }
            // copy directory
            foreach (string fullname in dirs)
            {
                CopyDirToDir(fullname, DstDir, move);
                Directory.Delete(fullname, true);
            }
        }
        static private void CopyFilesAndDirsToDir(ArrayList files, ArrayList dirs, string DstDir)
        {
            CopyFilesAndDirsToDir(files, dirs, DstDir, false);
        }
        static private void CopyDirToDir(string src, string dst, bool move)
        {
            ArrayList files = new ArrayList();
            ArrayList dirs = new ArrayList();
            DirectoryInfo di = new DirectoryInfo(dst);
            DirectoryInfo srcdi = new DirectoryInfo(src);
            foreach (FileInfo s in srcdi.GetFiles())
            {
                files.Add(s.FullName);
            }
            foreach (DirectoryInfo s in srcdi.GetDirectories())
            {
                dirs.Add(s.FullName);
            }
            // equiquile code block
            //dirs.AddRange(srcdi.GetDirectories());
            if (files.Count > 0 || dirs.Count > 0)
            {
                CopyFilesAndDirsToDir(files, dirs, CheckSlash(dst) + srcdi.Name, move);

            }
        }
        static private void CopyDirToDir(string src, string dst)
        {
            CopyDirToDir(src, dst, false);
        }
        static public long GetDirSize(string p)
        {
            long r = 0;
            DirectoryInfo di = new DirectoryInfo(p);
            foreach (FileInfo fi in di.GetFiles())
            {
                r += fi.Length;
            }
            foreach (DirectoryInfo fi in di.GetDirectories())
            {
                r += GetDirSize(fi.FullName);
            }
            return r;
        }

        public static bool EqualsDir(string dir, string d)
        {
            return CheckSlash(dir) == CheckSlash(d);
        }
        // return FileInfo
        public static object[] SearchFile(string filename, string dir)
        {
            ArrayList al = new ArrayList();
            if (IsDir(dir))
            {
                DirectoryInfo di = new DirectoryInfo(dir);
                al.AddRange(di.GetFiles(filename, SearchOption.AllDirectories));
                al.ToArray();
            }
            return al.ToArray();
        }
        public static bool IsDir(string file)
        {
            return Directory.Exists(file);
        }
        public static string ParentDir(string file)
        {
            string r = "";
            if (file == "") return "";
            //if (IsDir(file))
            if (true)
            {
                int index = file.LastIndexOf("\\");
                // delete all postfix \\
                while ((index == file.Length - 1) && (file.Length > 0))
                {
                    file = file.Substring(0, file.Length - 1);
                }
                index = file.LastIndexOf("\\");
                if (index < 0)
                {
                    DirectoryInfo di = new DirectoryInfo(file);
                    r = di.Root.ToString();
                }
                else
                {
                    r = file.Substring(0, index + 1);
                }
                return r;
            }
        }
        public static bool CheckUnc(string dir)
        {
            if (dir.Substring(0, 2) == "\\\\")//unc
            {
                string user = "";
                string pass = "";
                int re = -1;
                if (!NetDiskClass.LoginedDisk(dir, "", user, pass))
                {
                    if (AskPassword.get(ref user, ref pass))
                    {
                        re = NetDiskClass.NetDisk(dir, "", user, pass);
                        return 0 == re;                        
                    }
                    else
                        return false;
                }
                else
                    return true;
            }
            return true;
        }


        public static bool GetLoginInfo(ref string user, ref string pass)
        {
            user = "lcj";
            pass = "1";
            return true;
        }

        public static void CheckNoSlash(ref string dir)
        {
            if (dir.Substring(dir.Length - 1, 1) == "\\")
                dir = dir.Substring(0, dir.Length - 1);
        }

        public static bool IsRoot(string dir)
        {
            if (!IsUnc(dir))
            {
                DirectoryInfo di = new DirectoryInfo(dir);
                return di.ToString() == di.Root.ToString();
            }
            else
            {
                string t = dir.Substring(2, dir.Length - 2);
                CheckNoSlash(ref t);
                return t.LastIndexOf("\\") < 0;
            }
        }

        public static bool IsUnc(string dir)
        {
            return dir.IndexOf("\\\\") == 0;
        }

        public static void DeleteFileOrFolder(string filename)
        {
            if (IsDir(filename))
                DeleteDir(filename);
            else
            {
                FileUtils.DropReadOnly(filename);
                File.Delete(filename);
            }
        }

        public static void DeleteDir(string rootDir)
        {
            DirectoryInfo root = new DirectoryInfo(rootDir);
            FileInfo[] files = root.GetFiles();
            foreach (FileInfo file in files)
            {
                DeleteFileOrFolder(file.FullName);
            }
            DirectoryInfo[] dirs = root.GetDirectories();
            foreach (DirectoryInfo dir1 in dirs)
            {
                DeleteDir(dir1.FullName);
            }
            Directory.Delete(rootDir);
        }
        /// <summary>
        /// ensure file of directory exists,such as c:\\program files\easycmd\easycmd.exe,then ensure c:\\program files\easycmd\ exists 
        /// </summary>
        /// <param name="filePath">full file name </param>
        public static void EnsureDirExistsFor(String filePath)
        {
            String tempDirPath = GetDir(filePath);
            if (!System.IO.Directory.Exists(tempDirPath))
            {
                System.IO.Directory.CreateDirectory(tempDirPath);
            }
        }
        
        /// <summary>
        /// get total file count
        /// </summary>
        /// <param name="files">directory and file relate name list ,such as adir\\,afile.txt,afile2.txt ,etc </param>
        /// <param name="SrcDir">home dir of files ,such as c:\\windows\\system32\\</param>
        /// <returns></returns>
        public static int GetTotalFiles(IList<string> files, string SrcDir)
        {
            int answer = 0;
            foreach (string file in files)
            {
                string fullname = file;
                //fullname = FileUtils.CheckSlash(SrcDir) + fullname;
                //string srcName = (new DirectoryInfo(fullname).Name);
                if (Directory.Exists(fullname))
                {
                    answer += FileUtils.GetTotalFiles(fullname);
                }
                else
                {
                    answer++;
                }
            }
            return answer;
        }
        public static void ExecuteFile(string s)
        {
            const int ERROR_FILE_NOT_FOUND = 2;
            const int ERROR_ACCESS_DENIED = 5;

            Process myProcess = new Process();
            try
            {
                myProcess.StartInfo.FileName = "\"" + s + "\"";
                myProcess.StartInfo.Verb = "Open";
                myProcess.Start();
            }
            catch (Win32Exception e)
            {
                if (e.NativeErrorCode == ERROR_FILE_NOT_FOUND)
                {
                    MessageBox.Show(e.Message + ". Check the path.");
                }

                else if (e.NativeErrorCode == ERROR_ACCESS_DENIED)
                {
                    MessageBox.Show(e.Message +
                        ". You do not have permission to print this file.");
                }
            }
        }
        public string abc()
        {
            string abc = "dd";
            return abc;
        }


        public static string LastDir(string srcdir)
        {
            if (!Directory.Exists(srcdir)) return "";
            DirectoryInfo i = new DirectoryInfo(srcdir);
            return srcdir.Replace(i.Parent.ToString(), "");
        }

        public static string GetNewFile(string p)
        {
            string fileprefix = "newfile";
            string newfile = FileUtils.CheckSlash(p) + fileprefix + ".txt";
            int i = 0;
            while (File.Exists(newfile))
            {
                newfile = FileUtils.CheckSlash(p) + fileprefix + i.ToString() + ".txt";
                i++;
            }
            return newfile;
        }
        public static string GetNameOnly(string p)
        {
            return new FileInfo(p).Name;
        }
        public static string GetDir(string p)
        {
            return new FileInfo(p).DirectoryName;
        }
        public static int GetTotalFiles(string sourceFolder)
        {
            int answer = 0;
            string[] files = Directory.GetFiles(sourceFolder);
            answer += files.Length;
            string[] folders = Directory.GetDirectories(sourceFolder);
            foreach (string folder in folders)
            {
                //string name = Path.GetFileName(folder);
                answer += GetTotalFiles(folder);
            }
            return answer;
        }
        public static void DropReadOnly(string path)
        {
            if (File.Exists(path) && (File.GetAttributes(path) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
            {
                File.SetAttributes(path, FileAttributes.Normal);
            }
        }
        void test()
        {
            Console.WriteLine(GetNameOnly(@"C:\Program Files\1000tools\1000toolsreadme.txt"));
            Console.WriteLine(GetDir(@"C:\Program Files\1000tools\1000toolsreadme.txt"));
        }

        public static string GetExtention(string file)
        {
            string ext = new FileInfo(file).Extension;
            if (ext.Length > 1)
            {
                ext = ext.Substring(1, ext.Length - 1);
            }
            return ext;

        }
        public static string GetNumberPostFixFileName(string filename)
        {
            string _filename = "";
            for (int i = 0; true; i++)
            {
                _filename = Path.Combine(FileUtils.GetDir(filename), (FileUtils.GetNameWithoutExt(filename) + " " + i.ToString()));
                string _ext = FileUtils.GetExtention(filename); 
                if (_ext != string.Empty)
                    _filename += "." + FileUtils.GetExtention(filename);
                if (!File.Exists(_filename)&& !Directory.Exists(_filename)) return _filename;
            }
        }
        public static string GetSize(string file)
        {
            string size;
            try
            {
                FileInfo i = new FileInfo(file);
                size = i.Length.ToString();
            }
            catch
            {
                return "0";
            }
            return size;
        }

        internal static string GetNameWithoutExt(string filename)
        {
            FileInfo fi = new FileInfo(filename);
            int index = fi.Name.LastIndexOf(".");
            if (index == -1) return fi.Name;
            else
                return fi.Name.Substring(0,index);
        }
    }
}
